package org.lisy.designpattern.prototype;

/**
 * 原型模式
 * - 抽象原型 
 * - 具体原型
 * 优缺点:
 * - 优点:简化复杂对象的创建过程，方便扩展
 * - 缺点:每层类都需要支持深克隆，循环引用问题
 * 
 * @author lisy
 */
public class PrototypeMain {

	public static void main(String[] args) {
		// 测试浅克隆
		System.out.println("test shallow clone !");
		shallowCloneTest();
		// 测试深克隆
		System.out.println("test deep clone !");
		deepCloneTest();
	}

	private static void deepCloneTest() {
		Invoice invoice = getInstance();
		Invoice invoiceClone = (Invoice) invoice.getDeepCloneInstance(invoice);
		test(invoice, invoiceClone);
	}

	private static void shallowCloneTest() {
		Invoice invoice = getInstance();
		try {
			Invoice invoiceClone = (Invoice) invoice.getShallowCloneInstance();
			test(invoice, invoiceClone);
		} catch (CloneNotSupportedException e) {
			System.out.println("浅克隆异常！" + e.toString());
		}
	}

	private static Invoice getInstance() {
		Invoice invoice = new Invoice();
		invoice.setColor("bule");
		invoice.setTicketNo(001);
		invoice.setEffective(false);
		invoice.setCompanySeal(new Seal());
		return invoice;
	}

	private static void test(Invoice invoice, Invoice invoiceClone) {
		/**
		 * 验证对象是否同一个
		 */
		System.out.println("invoice: " + invoice.hashCode());
		System.out.println("clone invoice: " + invoiceClone.hashCode());
		System.out.println(invoice == invoiceClone);
		System.out.println("--------------------------");

		/**
		 * 验证基本数据类型是否相等
		 */
		System.out.println("ticketNo: " + invoice.getTicketNo());
		System.out.println("clone ticketNo: " + invoiceClone.getTicketNo());
		System.out.println(invoice.getTicketNo() == invoiceClone.getTicketNo());
		System.out.println("--------------------------");

		/**
		 * 验证引用数据类型是否相等
		 */
		System.out.println("color: " + invoice.getColor().hashCode());
		System.out.println("clone color: " + invoiceClone.getColor().hashCode());
		System.out.println(invoiceClone.getColor() == invoice.getColor());

		System.out.println("companySeal: " + invoice.getCompanySeal().hashCode());
		System.out.println("clone companySeal: " + invoiceClone.getCompanySeal().hashCode());
		System.out.println(invoice.getCompanySeal() == invoiceClone.getCompanySeal());
		System.out.println("--------------------------");

		/**
		 * 验证基本数据类型修改
		 */
		invoice.setTicketNo(2);
		System.out.println("ticketNo" + invoice);
		System.out.println("ticketNo" + invoiceClone);
		System.out.println("--------------------------");

		/**
		 * 验证基本数据类型保包装类
		 */
		invoice.setEffective(true);
		System.out.println("effective " + invoice);
		System.out.println("effective " + invoiceClone);
		System.out.println("--------------------------");

		/**
		 * 验证引用数据类型
		 */
		invoice.getCompanySeal().setName("验证引用数据类型");
		System.out.println("companySeal name " + invoice);
		System.out.println("companySeal name " + invoiceClone);
		System.out.println("==========================");
	}
}
